package com.vehicle.biz.core.impl;

import com.vehicle.biz.core.PlateDetectedBiz;
import com.vehicle.biz.core.support.PlateDetectSupport;
import com.vehicle.biz.core.support.PlateDetectSupportFactory;
import com.vehicle.constants.Constants;
import com.vehicle.domains.ctx.PlateDetectContext;
import com.vehicle.domains.entity.CameraEntity;
import com.vehicle.domains.entity.CommonVehicleEntity;
import com.vehicle.domains.info.HeartBeatInternalInfo;
import com.vehicle.domains.info.PlateDetectedInternalInfo;
import com.vehicle.domains.info.SnapshotInternalInfo;
import com.vehicle.enums.InOutTypeEnum;
import com.vehicle.enums.WorkModelEnum;
import com.vehicle.exception.VehicleAccessException;
import com.vehicle.service.CameraService;
import com.vehicle.service.CameraSnapshotService;
import com.vehicle.service.CommonVehicleService;
import com.vehicle.service.config.SystemConfig;
import com.vehicle.service.config.SystemConfigService;
import com.vehicle.utils.Base64ToImageUtil;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

@Service
public class PlateDetectedBizImpl implements PlateDetectedBiz {
    @Resource
    private CameraService cameraService;

    @Resource
    private SystemConfigService systemConfigService;

    @Resource
    private CommonVehicleService commonVehicleService;

    @Resource
    private PlateDetectSupportFactory plateDetectSupportFactory;
    @Resource
    private CameraSnapshotService cameraSnapshotService;



    @Override
    public Boolean receivePlateDetected(PlateDetectedInternalInfo plateDetectedInternalInfo) {

        //构建上下文对象，将需要的参数都封装起来
        PlateDetectContext plateDetectContext = new PlateDetectContext();
        BeanUtils.copyProperties(plateDetectedInternalInfo, plateDetectContext);

        String vehicleNumber = plateDetectedInternalInfo.getInternalVehicleInfo().getVehicleNumber();
        plateDetectContext.setVehicleNumber(vehicleNumber);
        //需要过滤的车牌号
        CommonVehicleEntity commonVehicleEntity =checkVehicleNumber(vehicleNumber);
        plateDetectContext.setCommonVehicleEntity(commonVehicleEntity);
        //获取相机信息
        CameraEntity cameraEntity = cameraService.getCameraByIp(plateDetectedInternalInfo.getInternalCameraInfo().getIp());
        if (cameraEntity == null) {
            throw VehicleAccessException.DATA_NOT_EXIST.newInstance("相机不存在");
        }
        plateDetectContext.setCameraEntity(cameraEntity);
        //车辆判断进入\台账
        doReceivePlateDetected(plateDetectContext);
        return null;
    }

    @Override
    public void receiveHeartBeat(HeartBeatInternalInfo heartBeatInternalInfo) {
        //
    }

    @Override
    public void receiveSnapshot(SnapshotInternalInfo snapshotInternalInfo) {
        CameraEntity cameraEntity = cameraService.getCameraByIp(snapshotInternalInfo.getIp());
        if (cameraEntity == null) {
            throw VehicleAccessException.DATA_NOT_EXIST.newInstance("相机不存在");
        }

        //判断是否是抓拍模式
        if (!WorkModelEnum.SNAP.name().equals(cameraEntity.getWorkMode())) {
            return;
        }

        String url = Base64ToImageUtil.saveBase64(snapshotInternalInfo.getImageFile(), Constants.PICTURE_FILE_SNAP_PATH);

        cameraSnapshotService.storeSnapshotImage(url, snapshotInternalInfo.getIp());

    }

    public void doReceivePlateDetected(PlateDetectContext plateDetectContext){

        PlateDetectSupport plateDetectSupport = plateDetectSupportFactory.getSupport(plateDetectContext.getVehicleType());

        //判断车辆能否通行
        if (InOutTypeEnum.IN.name().equals(plateDetectContext.getInOutType())) {
            plateDetectSupport.processIn(plateDetectContext);
        } else {
            plateDetectSupport.processOut(plateDetectContext);
        }

        //记录台账信息
        if (InOutTypeEnum.IN.name().equals(plateDetectContext.getInOutType())) {
            plateDetectSupport.recordIn(plateDetectContext);
        } else {
            plateDetectSupport.recordOut(plateDetectContext);
        }

    }

    private CommonVehicleEntity checkVehicleNumber(String vehicleNumber){
        CommonVehicleEntity commonVehicleEntity =commonVehicleService.getCommonVehicleByVehicleNumber(vehicleNumber);

        String ignoreVehicleNumberRule = systemConfigService.get(SystemConfig.ignoreVehicleNumber);

        if (vehicleNumber.matches(ignoreVehicleNumberRule)) {
            throw VehicleAccessException.SYSTEM_ERROR.newInstance("vehicleNumber is ignore vehicleNumber");
        }

        return commonVehicleEntity;
    }
}
